package org.grow.present.controller.purchase;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.grow.present.dto.ApplierPurchaseQC;
import org.grow.present.dto.AuditorPurchaseQC;
import org.grow.present.dto.ExpensesAnaDetailQC;
import org.grow.present.entity.*;
import org.grow.present.entity.enums.PurchaseBillState;
import org.grow.present.exception.BillStateException;
import org.grow.present.exception.MissTargetException;
import org.grow.present.interceptor.AuthInterceptor;
import org.grow.present.mapper.DepartmentMapper;
import org.grow.present.mapper.ExpensesAnalysisMapper;
import org.grow.present.mapper.PurchaseBillMapper;
import org.grow.present.service.CodeGenerator;
import org.grow.present.service.PurchaseBillService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Month;
import java.util.List;

/**
 * @Author: xwg
 * @CreateDate: 2024/6/6
 */
@Slf4j
@RestController
@RequestMapping("/purchase")
public class PurchaseController {
    @Autowired
    private CodeGenerator codeGenerator;

    @Autowired
    private PurchaseBillMapper mapper;
    @Autowired
    private PurchaseBillService service;


    @PostMapping("/insert")
    public PurchaseBill insert(@RequestBody PurchaseBill purchaseBill) {
        String code = codeGenerator.nextCode("PB");
        PurchaseBill pb = new PurchaseBill();
//       core
        pb.setBillId(code);
        pb.setBillState(PurchaseBillState.toSubmit);
//      信任前端传递 的属性 supplier供货单位	orderDate订购日期	receiveDate交货日期
        pb.setSupplier(purchaseBill.getSupplier());
        pb.setOrderDate(purchaseBill.getOrderDate());
        pb.setReceiveDate(purchaseBill.getReceiveDate());
        ;
//        处理子表
        Double amount = 0d;
//          purchaseBill.
        List<PurchaseItem> items = purchaseBill.getItems();
        for (int i = 0; i < items.size(); i++) {
            PurchaseItem item = items.get(i);
            item.setBillFk(pb.getBillId());
            item.setItemId(i);
            item.setPriority(i);
            amount += item.getPrice().doubleValue() * item.getQuantity();
        }
        pb.setAmount(new BigDecimal(amount));
        pb.setNextItemId(items.size());
        pb.setItems(purchaseBill.getItems());
//        处理身份
        pb.setApplier(AuthInterceptor.getUID());
        pb.setUpdateTime(LocalDateTime.now());
        pb.setDepartmentFk("");
        int i = mapper.insert(pb);
        int j = mapper.saveItems(items);
        System.out.println(i);
        System.out.println(j);
        return pb;
    }

//    public Material modifyById(@RequestBody Material material) {
//        Material db = mapper.selectById(material.getMaterialCode());
//        if (db == null) {
//            throw new MissTargetException("待查看的数据不存在");
//        }
//        db.setMaterialLable(material.getMaterialLable());
//        db.setSuggestPrice(material.getSuggestPrice());
//        db.setMaterialType(material.getMaterialType());
////
////        BeanUtils.copyProperties(db, material);
//        int i = mapper.updateById(db);
//        return db;
//    }

    @GetMapping("/find/{id}")
    public PurchaseBill findById(@PathVariable String id) {
        PurchaseBill purchaseBill = mapper.findWholeById(id);
        if (purchaseBill == null) {
            throw new MissTargetException("待查看的数据不存在");
        }
        return purchaseBill;
    }

    @DeleteMapping("/remove/{id}")
    public String removeById(@PathVariable String id) {
        PurchaseBill db = mapper.selectById(id);
        if (db == null) {
            throw new MissTargetException("remove failed");
        }
        if (db.getBillState() != PurchaseBillState.toSubmit) {
            throw new BillStateException("已提交或已审核的购物不能删除");
        }
        service.removeWhole(db);
        return id;
    }

    // @Post('/query/applier')
    @PostMapping("/query/applier")
    public PageResults<PurchaseBill> query4Applier(@RequestBody ApplierPurchaseQC qc) {
        Page<PurchaseBill> page = Page.of(qc.getPageNum(), qc.getPageSize());
        String UID = AuthInterceptor.getUID();
        Page<PurchaseBill> page1 = mapper.dynamicQueryApplier(page, qc, UID);
        return PageResults.createByIPage(page);
    }

    @PostMapping("/query/auditor")
    public PageResults<PurchaseBill> query4Auditor(@RequestBody AuditorPurchaseQC qc) {
        Page<PurchaseBill> page = Page.of(qc.getPageNum(), qc.getPageSize());
        String UID = AuthInterceptor.getUID();
        System.out.println(qc);
        Page<PurchaseBill> page1 = mapper.dynamicQueryAuditor(page, qc, UID);
        return PageResults.createByIPage(page);
    }

    //      @Put('/modify')
    @PutMapping("/modify")
    public PurchaseBill modify(@RequestBody PurchaseBill purchaseBill) {
        String billId = purchaseBill.getBillId();
        PurchaseBill db = mapper.selectById(billId);
        System.out.println(db);
        if (db == null) {
            throw new MissTargetException("待修改的数据不存在");
        }
        if (db.getBillState() != PurchaseBillState.toSubmit) {
            throw new BillStateException("只有未提交状态才能修改'");
        }
        db.setBillState(PurchaseBillState.toSubmit);
//        // supplier供货单位	orderDate订购日期	receiveDate交货日期

        db.setSupplier(purchaseBill.getSupplier());
        db.setOrderDate(purchaseBill.getOrderDate());
        db.setReceiveDate(purchaseBill.getReceiveDate());

        //        处理子表
        Double amount = 0d;
//          purchaseBill.
        List<PurchaseItem> items = purchaseBill.getItems();
        for (int i = 0; i < items.size(); i++) {
            PurchaseItem item = items.get(i);
            item.setBillFk(db.getBillId());
            item.setItemId(i);
            item.setPriority(i);
            amount += item.getPrice().doubleValue() * item.getQuantity();
        }
        db.setAmount(new BigDecimal(amount));
        db.setNextItemId(items.size());
        db.setItems(purchaseBill.getItems());

        db.setApplier(AuthInterceptor.getUID());
        db.setUpdateTime(LocalDateTime.now());

//        persist // 对于子表 先清空 在追加 适合条目数小于10的时候
        mapper.updateById(db);
        mapper.removeItems(db.getBillId());
        mapper.saveItems(db.getItems());
        return db;
    }

    // 提交 审核 重交 三者 跟子表完全无关
//    @Put('/submit')
    @PutMapping("/submit")
    public PurchaseBill submit(@RequestBody PurchaseBill purchaseBill) {
        String auditor = purchaseBill.getAuditor();
        PurchaseBill db = mapper.selectById(purchaseBill.getBillId());
        if (db == null) {
            throw new MissTargetException("待提交的数据不存在");
        }
        if (db.getBillState() != PurchaseBillState.toSubmit) {
            throw new BillStateException("只有未提交状态才能提交'");
        }
        db.setBillState(PurchaseBillState.toAudit);

        db.setAuditor(auditor);
        db.setApplyTime(LocalDateTime.now());
        db.setUpdateTime(LocalDateTime.now());
        mapper.updateById(db);
        return db;
    }

    // 打回重交
//  @Put('/resent')
    @PutMapping("/resent")
    public PurchaseBill resent(@RequestBody PurchaseBill purchaseBill) {
        PurchaseBill db = mapper.selectById(purchaseBill.getBillId());
        if (db == null) {
            throw new MissTargetException("待重交数据不存在");
        }
        if (db.getBillState() != PurchaseBillState.toAudit) {
            throw new BillStateException("只有待审核状态才能打回重交'");
        }
        db.setBillState(PurchaseBillState.toSubmit);
        if (StringUtils.hasText(db.getAuditMsg())) {
            db.setHistory(db.getHistory() + ":" + db.getAuditMsg());
        }
        db.setAuditMsg(purchaseBill.getAuditMsg());
        db.setAuditTime(null);
        db.setUpdateTime(LocalDateTime.now());
        mapper.updateById(db);
        return db;
    }
    @Autowired
    private ExpensesAnalysisMapper expensesAnalysisMapper;
    @Autowired
    private DepartmentMapper departmentMapper;

    //    批准通过
//      @Put('/audit')
    @PutMapping("/audit")
    public PurchaseBill audit(@RequestBody PurchaseBill purchaseBill) {
        PurchaseBill db = mapper.selectById(purchaseBill.getBillId());
        if (db == null) {
            throw new MissTargetException("待审核数据不存在");
        }
        if (db.getBillState() != PurchaseBillState.toAudit) {
            throw new BillStateException("只有待审核状态才能审核'");
        }
        db.setBillState(PurchaseBillState.auditted);
        if (StringUtils.hasText(db.getAuditMsg())) {
            db.setHistory(db.getHistory() + ":" + db.getAuditMsg());
        }
        db.setAuditMsg(purchaseBill.getAuditMsg());
        db.setAuditTime(LocalDateTime.now());
        db.setUpdateTime(LocalDateTime.now());

        LocalDate naturalMonth = LocalDate.now().withDayOfMonth(1);

        Department d = departmentMapper.findBySupervisor(AuthInterceptor.getUID());
        if(d==null){
            throw new MissTargetException("当前用户并不是部门主管,无权审批");
        }
        String departmentId = d.getDepartmentId();
        db.setDepartmentFk(departmentId);
        ExpensesAnalysis ea = expensesAnalysisMapper.findByDepartmentAndNaturalMonth(departmentId, naturalMonth);
        if(ea==null){
            ExpensesAnalysis newEa = new ExpensesAnalysis();
            newEa.setId(0);
            newEa.setVersion(0);
            newEa.setDepartmentFk(departmentId);
            newEa.setNaturalMonth(naturalMonth);
            newEa.setExpenses(purchaseBill.getAmount());
            expensesAnalysisMapper.insert(newEa);
        }else{
            BigDecimal expenses = ea.getExpenses();
            BigDecimal finalValue = expenses.add(purchaseBill.getAmount());
            ea.setExpenses(finalValue);
            expensesAnalysisMapper.updateById(ea);
        }
        mapper.updateById(db);
        return db;
    }
//    統計分析頁面需要根據年月份與部門查詢開支的詳情
    @PostMapping("/query4AnaDetails")
    public Page<PurchaseBill> query4AnaDetails(@RequestBody ExpensesAnaDetailQC qc){

        Page<PurchaseBill> page = Page.of(qc.getPageNum(), qc.getPageSize());
//        String UID = AuthInterceptor.getUID();
       return mapper.anaQuery(page, qc);
    }
}
